package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"github.com/google/shlex"
	"io"
	"os"
	"regexp"
	"strings"
)

type PathInfo struct {
	Host         string `json:"host"`
	Channel      string `json:"channel"`
	Scsiid       string `json:"scsiid"`
	Lun          string `json:"lun"`
	DevNode      string `json:"devnode"`
	Major        string `json:"major"`
	Minor        string `json:"minor"`
	DmStatus     string `json:"dm_status"`
	PathStatus   string `json:"path_status"`
	OnlineStatus string `json:"online_status"`
}

func main() {
	tempParsingData := make(map[string]string)
	pathParsingData := make(map[string]string)
	pathsParsingData := make(map[string]map[string]string)
	var parsedData []map[string]string
	var paths []map[string]string
	var pathsEmpty []map[string]string
	thisIsANewBlock := false

	filePth := "E:/application/go_learning/multipath/result2.txt"
	f, err := os.Open(filePth)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	bfRd := bufio.NewReader(f)
	for {
		line, err := bfRd.ReadBytes('\n')
		if byteMatchResult, _ := regexp.Match(`^\w`, line); byteMatchResult {
			if byteMatchResult, _ := regexp.Match(`^size`, line); byteMatchResult {
				a, _ := shlex.Split(string(line))
				tempParsingData["size"] = strings.Split(a[0], "=")[1]
				tempParsingData["features"] = strings.Split(a[1], "=")[1]
				tempParsingData["hwhandler"] = strings.Split(a[2], "=")[1]
				tempParsingData["write_permission"] = strings.Split(a[3], "=")[1]
			} else {
				thisIsANewBlock = true

				if len(tempParsingData) > 0 && thisIsANewBlock {
					parsedData = append(parsedData, tempParsingData)
					tempParsingData = make(map[string]string)
					thisIsANewBlock = false
				}

				if byteMatchResult, _ := regexp.Match(`^[\w]{33}`, line); byteMatchResult {
					a, _ := shlex.Split(string(line))
					tempParsingData["wwid"] = a[0]
					tempParsingData["dm_device_name"] = a[1]
					tempParsingData["vendor"] = a[2]
				} else if byteMatchResult, _ := regexp.Match(`^.*\([\w]{33}\)`, line); byteMatchResult {
					a, _ := shlex.Split(string(line))
					tempParsingData["alias"] = a[0]
					tempParsingData["wwid"] = strings.Trim(a[1], "()")
					tempParsingData["dm_device_name"] = a[2]
					tempParsingData["vendor"] = a[3]
				} else if byteMatchResult, _ := regexp.Match(`^[\w]{17}`, line); byteMatchResult {
					a, _ := shlex.Split(string(line))
					tempParsingData["wwid"] = a[0]
					tempParsingData["dm_device_name"] = a[1]
					tempParsingData["vendor"] = a[2]
				} else if byteMatchResult, _ := regexp.Match(`^.*\([\w]{17}\)`, line); byteMatchResult {
					a, _ := shlex.Split(string(line))
					tempParsingData["alias"] = a[0]
					tempParsingData["wwid"] = strings.Trim(a[1], "()")
					tempParsingData["dm_device_name"] = a[2]
					tempParsingData["vendor"] = a[3]
				}
			}
		} else {
			if byteMatchResult, _ := regexp.Match(`.*-\+-`, line); byteMatchResult {
				a, _ := shlex.Split(string(line))
				tempParsingData["scheduling_policy"] = strings.Split(a[1], "=")[1]
				tempParsingData["prio"] = strings.Split(a[2], "=")[1]
				tempParsingData["status"] = strings.Split(a[3], "=")[1]
				paths = pathsEmpty
				pathsParsingData = make(map[string]map[string]string)
			} else if byteMatchResult, _ := regexp.Match(`.*-`, line); byteMatchResult {
				a := strings.Fields(string(line))
				pathParsingData = make(map[string]string)
				pathParsingData["host"] = strings.Split(a[1], ":")[0]
				pathParsingData["channel"] = strings.Split(a[1], ":")[1]
				pathParsingData["scsiid"] = strings.Split(a[1], ":")[2]
				pathParsingData["lun"] = strings.Split(a[1], ":")[3]
				pathParsingData["devnode"] = a[2]
				pathParsingData["major"] = strings.Split(a[3], ":")[0]
				pathParsingData["minor"] = strings.Split(a[3], ":")[1]
				pathParsingData["dm_status"] = a[4]
				pathParsingData["path_status"] = a[5]
				pathParsingData["online_status"] = a[6]
				paths = append(paths, pathParsingData)
				pathsParsingData[a[1]] = pathParsingData
				paths, _ := json.Marshal(paths)
				pathsParsingData, _ := json.Marshal(pathsParsingData)
				tempParsingData["paths"] = string(paths)
				tempParsingData["pathsParsingData"] = string(pathsParsingData)
			}
		}

		//遇到任何错误立即返回，并忽略 EOF 错误信息
		if err != nil {
			if err == io.EOF {
				break
			}
		}
	}
	if len(tempParsingData) > 0 {
		parsedData = append(parsedData, tempParsingData)
		tempParsingData = make(map[string]string)
	}
	//fmt.Println(parsedData)

	for i := 0; i < len(parsedData); i++ {
		//fmt.Println(i, parsedData[i])
		//fmt.Println(parsedData[i]["paths"])
		//fmt.Println(parsedData[i]["pathsParsingData"])
		//var pathInfos PathInfo
		//json.Unmarshal([]byte(parsedData[i]["paths"]), &pathInfos)
		//for _, pathInfo := range parsedData[i]["pathsParsingData"] {
		//	var path PathInfo
		//	json.Unmarshal(pathInfo, &path)
		//	fmt.Println(path.Host, path.Lun, path.Channel, path.Scsiid, path.DevNode, path.Major,
		//		path.Minor, path.DmStatus, path.PathStatus, path.OnlineStatus)
		//}

		pathInfos := make(map[string]map[string]string)
		json.Unmarshal([]byte(parsedData[i]["pathsParsingData"]), &pathInfos)
		for _, pathInfo := range pathInfos {
			fmt.Println(pathInfo)
			fmt.Println(pathInfo["host"], pathInfo["lun"], pathInfo["channel"], pathInfo["scsiid"], pathInfo["devnode"],
				pathInfo["major"], pathInfo["minor"], pathInfo["dm_status"], pathInfo["path_status"], pathInfo["online_status"])
		}
	}
}
